package cn.tedu.ivos.application.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.dto.ApplicationQuery;
import cn.tedu.ivos.application.pojo.dto.ApplicationSaveParam;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.application.pojo.vo.ApplicationVO;
import cn.tedu.ivos.application.service.ApplicationService;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Transactional
@Slf4j
@Service
public class ApplicationServiceImpl implements ApplicationService {
    @Autowired
    ApplicationMapper applicationMapper;
    @Autowired
    AuditService auditService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    AuditMapper auditMapper;

    @Override
    public void save(ApplicationSaveParam applicationSaveParam) {
        log.debug("保存申请单业务：applicationSaveParam={}",applicationSaveParam);
        Application application =new Application();
        BeanUtils.copyProperties(applicationSaveParam,application);
        //新增申请单，初始状态为 已发起
        application.setStatus(ApplicationStatusEnum.PENDING.getCode());
        application.setCreateTime(new Date());
//        遇到的问题：新增申请单对应的审批单数据时，审批单数据没有申请单的id
//        原因：id是一个比较特殊的属性，无法通过任何select条件获取：
//        解决方案：给insert方法对应的sql加上： userGeneratedKeys="true" keyProperty="id"
//        让JDBC为当前的application对象自动昂生成自增主键，并且把生成饿主键赋值给当前
//        的application对象的id字段
        applicationMapper.insert(application);

        //还需要调用审批业务层，为当前申请单同步新增对应的审批数据
        auditService.insertAudit(application);
    }

    @Override
    public List<ApplicationVO> selectApplication(ApplicationQuery applicationQuery) {
        log.debug("查询申请单业务：applicationQuery={}",applicationQuery);
        List<ApplicationVO> list = applicationMapper.selectApplication(applicationQuery);
        //遍历每一个申请单，依次为每个遍历的申请单添加审批人数据：
        for (int i =0;i<list.size();i++){
            ApplicationVO applicationVO = list.get(i);
            //处理当前的申请单VO，给他添加审批人数据：
            assignAuditUserList(applicationVO);
        }
        return list;
    }
    //添加审批人数据
/*
    本方法用于给当前传入的申请单VO的审批人数据赋值（auditUserIdList与auditUsernameList）
 */

    private void assignAuditUserList(ApplicationVO applicationVO) {
//        1、准备空集合 用来保存申请单对应的审批人姓名与id集合：
        List<String> auditUsernameList= new ArrayList<>();
        List<Long> auditUserIdList =new ArrayList<>();
        //2、根据传入的申请单对象id查出对应的审批数据：注意：审批数据可能有多条：
        List<AuditVO> auditVOList =auditService.selectAuditByApplicationId(
                applicationVO.getId());
        //3、依次遍历每一个审批单对象：
        for (int i =0;i<auditVOList.size();i++){
            AuditVO auditVO = auditVOList.get(i);
            //4、取出审批VO中的审批人id，装入上方的空集合中
            Long id = auditVO.getAuditUserId();
            auditUserIdList.add(id);
            //5、根据刚刚取出来的审批人id，查出此人姓名装入上方的空集合中
            UserVO userVO = userMapper.selectById(id);
            auditUsernameList.add(userVO.getUsername());
        }
        //6、准备一个拼接工具，帮我们将所有的审批人姓名连城一个字符窜：
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username:auditUsernameList){
            stringJoiner.add(username);
        }
        //将拼接好的审批人姓名字符串赋值给申请单VO的AuditUsernameList属性
        applicationVO.setAuditUsernameList(stringJoiner.toString());
        //将准备好的审批人的id集合赋值给申请单VO的AuditUserUIdList属性
        applicationVO.setAuditUserIdList(auditUserIdList);
    }


    @Override
    public void updateApplicationStatus(Long id) {
        log.debug("修改申请单状态业务：id={}",id);
        Application application = new Application();
        application.setId(id);
//        设置当前申请单的状态为撤销
        application.setStatus(ApplicationStatusEnum.CANCEL.getCode());
        application.setUpdateTime(new Date());
        applicationMapper.update(application);

//        还需要删除除此对应的所有审批单数据
        auditMapper.deleteAuditByApplicationId(id);
    }
}
